import Vue from 'vue'
import { Toast } from 'vant'
// 直接导入store
import store from '../store'
// 直接导入router
import router from '../router'
// 导入axios
import axios from 'axios'
axios.defaults.baseURL = 'http://toutiao.itheima.net'
// 如何让所有.vue文件里都能访问？
// 原理是用到原型链，用了下面这句话后，那么在所有的.vue文件里
// 都可以通过 this.$axios 来使用 axios
Vue.prototype.$axios = axios

// 给axios克隆了一个新对象出来，但是没有请求拦截
var instance = axios.create({
    baseURL: 'http://toutiao.itheima.net',
});



// 添加请求拦截器
axios.interceptors.request.use(function (config) {

    // 只要你用这个axios对象发请求，它都会被拦截下来
    // 调用这个函数
    if (store.state.tokenObj.token) {
        // 先判断有没有token，有token才加到请求头里面
        config.headers.Authorization = 'Bearer ' + store.state.tokenObj.token
    }
    return config;
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;

}, async function (error) {
    // console.dir(error)
    // 错误一定是过期吗？不一定，我们还要判断是不是401错误
    if (error.response.status == 401) {

        try {
            // 这里代表token过期，就利用refresh_token去请求新的token
            // 只要是通过axios这个对象发的
            // 那么一定会触发axios的请求拦截
            // 而我们又不想让它触发请求拦截
            // 所以我们就不能用axios这个对象发请求
            // 但是又要用一样的发请求的功能
            // 所以我就克隆一个还没加请求拦截的axios对象
            // 那这个克隆出来的对象就既有axios的功能，又没有请求拦截
            let res = await instance({
                url: '/v1_0/authorizations',
                method: 'put',
                headers: {
                    Authorization: 'Bearer ' + store.state.tokenObj.refresh_token
                }
            })

            // 拿到新token了，就把新token替换到vuex和localStorage里
            store.commit('setToken', {
                token: res.data.data.token,
                refresh_token: store.state.tokenObj.refresh_token
            })

            return axios(error.config)
        }
        catch {

            // 能进入到catch证明连refresh_token都过期了
            // 那么就让它重新登录即可
            // 提示一下，登录状态已过期请重新登录
            Toast.fail('登录状态过期，请重新登录')
            // 打回登录页
            router.push('/login')
        }



    } else {
        // 别的错误该怎么报错就怎么报错
        return Promise.reject(error);
    }
});
